// 从 ComfyUI 的静态目录导入 app 对象
import { app } from "/scripts/app.js";
import { logger } from "../js/logger.js";

// 测试套件类
class NodeTestSuite {
    constructor() {
        this.testResults = [];
        this.currentTest = null;
        this.logger = logger;
        this.logger.setPrefix('TestSuite');
    }

    // 添加测试结果
    addResult(testName, success, message) {
        this.testResults.push({
            name: testName,
            success,
            message,
            timestamp: new Date().toISOString()
        });
        this.updateUI();
    }

    // 更新UI显示
    updateUI() {
        const output = document.getElementById('test-output');
        if (output) {
            output.innerHTML = this.testResults.map(result => 
                `<div class="test-result ${result.success ? 'success' : 'failure'}">
                    <span class="test-name">${result.name}</span>
                    <span class="test-status">${result.success ? '✓' : '✗'}</span>
                    <span class="test-message">${result.message}</span>
                    <span class="test-time">${new Date(result.timestamp).toLocaleTimeString()}</span>
                </div>`
            ).join('');
        }
    }

    // 获取对象的所有方法的辅助函数
    getAllMethods(obj) {
        let methods = new Set();
        
        // 获取对象自身的所有属性（包括方法）
        Object.getOwnPropertyNames(obj).forEach(prop => {
            if (typeof obj[prop] === 'function') {
                methods.add(prop);
            }
        });
        
        // 获取原型链上的方法
        let proto = Object.getPrototypeOf(obj);
        while (proto && proto !== Object.prototype) {
            Object.getOwnPropertyNames(proto).forEach(prop => {
                if (typeof proto[prop] === 'function') {
                    methods.add(prop);
                }
            });
            proto = Object.getPrototypeOf(proto);
        }
        
        return Array.from(methods);
    }

    // 打印对象方法的辅助函数
    printObjectMethods(obj, objName = "对象") {
        console.log(`${objName}的所有方法:`);
        const methods = this.getAllMethods(obj);
        console.log("方法列表:", methods);
        
        console.log(`${objName}方法详细信息:`);
        methods.forEach(methodName => {
            try {
                console.log(`${methodName}:`, obj[methodName].toString());
            } catch (e) {
                console.log(`${methodName}: 无法获取方法内容`);
            }
        });
    }

    // 测试节点创建
    async testNodeCreation() {
        this.currentTest = '节点创建测试';
        try {
            // 使用 LiteGraph API 创建节点
            const node = LiteGraph.createNode("TestNode");
            this.logger.analyzeObject(node, "创建的节点", "创建测试");
            
            app.graph.add(node);
            
            if (node) {
                this.addResult(this.currentTest, true, "节点创建成功");
                return node;
            } else {
                this.addResult(this.currentTest, false, "节点创建失败");
                return null;
            }
        } catch (error) {
            this.logger.error(error.message, "创建测试");
            this.addResult(this.currentTest, false, `节点创建错误: ${error.message}`);
            return null;
        }
    }

    // 测试节点属性
    async testNodeProperties(node) {
        this.currentTest = '节点属性测试';
        try {
            this.logger.group("属性测试");
            this.logger.analyzeObject(node, "测试节点", "属性测试");
            
            const requiredProps = ['id', 'type', 'inputs', 'outputs', 'widgets'];
            const missingProps = requiredProps.filter(prop => !(prop in node));
            
            // 打印每个属性的值
            requiredProps.forEach(prop => {
                if (node[prop] && typeof node[prop] === 'object') {
                    this.logger.analyzeObject(node[prop], `${prop}对象`, "属性测试");
                }
            });
            
            this.logger.groupEnd();
            
            if (missingProps.length === 0) {
                this.addResult(this.currentTest, true, "所有必需属性都存在");
                return true;
            } else {
                this.addResult(this.currentTest, false, `缺少属性: ${missingProps.join(', ')}`);
                return false;
            }
        } catch (error) {
            this.logger.error(error.message, "属性测试");
            this.addResult(this.currentTest, false, `属性测试错误: ${error.message}`);
            return false;
        }
    }

    // 测试节点连接
    async testNodeConnections(node1, node2) {
        this.currentTest = '节点连接测试';
        try {
            this.logger.group("连接测试");
            
            // 分析两个节点
            this.logger.analyzeObject(node1, "节点1", "连接测试");
            this.logger.analyzeObject(node2, "节点2", "连接测试");

            const output = node1.outputs[0];
            const input = node2.inputs[0];
            
            // 分析输入输出端口
            if (output) this.logger.analyzeObject(output, "输出端口", "连接测试");
            if (input) this.logger.analyzeObject(input, "输入端口", "连接测试");

            if (!output || !input) {
                this.logger.warn("节点没有可用的输入/输出端口", "连接测试");
                this.addResult(this.currentTest, false, "节点没有可用的输入/输出端口");
                return false;
            }

            // 创建连接
            node1.connect(0, node2, 0);
            
            // 检查连接是否成功
            const connections = node1.outputs[0].links;
            if (connections) this.logger.analyzeObject(connections, "连接对象", "连接测试");
            const isConnected = connections && connections.length > 0;
            
            this.logger.groupEnd();
            
            if (isConnected) {
                this.addResult(this.currentTest, true, "节点连接成功");
                return true;
            } else {
                this.addResult(this.currentTest, false, "节点连接失败");
                return false;
            }
        } catch (error) {
            this.logger.error(error.message, "连接测试");
            this.addResult(this.currentTest, false, `连接测试错误: ${error.message}`);
            return false;
        }
    }

    // 测试工作流执行
    async testWorkflowExecution() {
        this.currentTest = '工作流执行测试';
        try {
            this.logger.group("工作流测试");
            
            // 检查图表是否有节点
            if (app.graph._nodes && app.graph._nodes.length > 0) {
                // 分析工作流
                this.logger.analyzeObject(app.graph, "工作流图表", "工作流测试");
                
                // 尝试获取工作流
                const workflow = app.graph.serialize();
                if (workflow) {
                    this.logger.analyzeObject(workflow, "序列化后的工作流", "工作流测试");
                    this.addResult(this.currentTest, true, "工作流执行成功");
                    return true;
                } else {
                    this.logger.warn("无法序列化工作流", "工作流测试");
                    this.addResult(this.currentTest, false, "无法序列化工作流");
                    return false;
                }
            } else {
                this.logger.warn("工作流中没有节点", "工作流测试");
                this.addResult(this.currentTest, false, "工作流中没有节点");
                return false;
            }
            
            this.logger.groupEnd();
        } catch (error) {
            this.logger.error(error.message, "工作流测试");
            this.addResult(this.currentTest, false, `工作流执行错误: ${error.message}`);
            return false;
        }
    }

    // 运行所有测试
    async runAllTests() {
        this.logger.info("开始运行所有测试", "测试套件");
        this.logger.time("测试总耗时");
        
        // 创建测试节点
        const node1 = await this.testNodeCreation();
        if (!node1) return;
        
        // 测试节点属性
        await this.testNodeProperties(node1);
        
        // 创建第二个节点并测试连接
        const node2 = await this.testNodeCreation();
        if (node2) {
            await this.testNodeConnections(node1, node2);
        }
        
        // 测试工作流执行
        await this.testWorkflowExecution();
        
        this.logger.timeEnd("测试总耗时");
        this.logger.info("所有测试完成", "测试套件");
    }

    // 清除测试结果
    clearResults() {
        this.testResults = [];
        this.updateUI();
        this.logger.info("测试结果已清除", "测试套件");
    }
}

// 创建测试套件实例
const testSuite = new NodeTestSuite();

// 注册扩展
app.registerExtension({
    name: "comfy.node_test_suite",
    
    // 定义测试命令
    commands: [
        {
            id: "node_test.run_all",
            label: "运行节点测试",
            function: async () => {
                await testSuite.runAllTests();
            }
        },
        {
            id: "node_test.clear",
            label: "清除测试结果",
            function: () => {
                testSuite.clearResults();
            }
        }
    ],
    
    // 定义快捷键
    keybindings: [
        {
            combo: { key: "n", ctrl: true, alt: true },
            commandId: "node_test.run_all"
        },
        {
            combo: { key: "r", ctrl: true, alt: true },
            commandId: "node_test.clear"
        }
    ],
    
    // 定义菜单命令
    menuCommands: [
        {
            path: ["测试"],
            commands: ["node_test.run_all", "node_test.clear"]
        }
    ],
    
    // 扩展初始化
    async setup() {
        console.log("【测试套件】初始化");
        app.extensionManager.registerSidebarTab({
            id: "customSidebar",
            icon: "icon-clear",
            title: "自定义标签页",
            tooltip: "我的自定义侧边栏标签页",
            type: "custom",
            render: (el) => {
              el.innerHTML = '<div>这是我的自定义侧边栏内容</div>';
            }
          });
        // 注册侧边栏标签页
        app.extensionManager.registerSidebarTab({
            id: "node_test_suite",
            icon: "icon-play",
            title: "节点测试套件",
            tooltip: "ComfyUI节点测试工具",
            type: "custom",
            render: (el) => {
                el.innerHTML = `
                    <div class="test-suite-panel">
                        <h2>节点测试套件1</h2>
                        <div class="test-controls">
                            <button id="run-all-tests" class="test-button">
                                <span class="icon-test icon-run-test"></span>
                                运行所有测试1
                            </button>
                            <button id="clear-tests" class="test-button">
                                <span class="icon-test icon-clear-test"></span>
                                清除测试结果
                            </button>
                        </div>
                        <div class="test-results">
                            <h3>测试结果</h3>
                            <div id="test-output"></div>
                        </div>
                    </div>
                `;
                
                // 添加按钮事件监听
                document.getElementById("run-all-tests").addEventListener("click", () => {
                    app.extensionManager.commands["node_test.run_all"].function();
                });
                
                document.getElementById("clear-tests").addEventListener("click", () => {
                    app.extensionManager.commands["node_test.clear"].function();
                });
            }
        });
        
        // 添加样式
        const style = document.createElement('style');
        style.textContent = `
            .test-suite-panel {
                padding: 15px;
                font-family: system-ui, -apple-system, sans-serif;
            }
            .test-controls {
                display: flex;
                gap: 10px;
                margin: 15px 0;
            }
            .test-button {
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 8px 16px;
                background-color: #4CAF50;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
                transition: background-color 0.3s;
            }
            .test-button:hover {
                background-color: #45a049;
            }
            .icon-test {
                display: inline-block;
                width: 24px;
                height: 24px;
                background-size: contain;
                background-repeat: no-repeat;
                background-position: center;
                vertical-align: middle;
            }
            .icon-run-test {
                background-image: url('../assets/play.svg');
            }
            .icon-clear-test {
                background-image: url('../assets/clear.svg');
            }
            .test-results {
                margin-top: 20px;
                padding: 15px;
                background-color: #f5f5f5;
                border-radius: 6px;
                max-height: 400px;
                overflow-y: auto;
            }
            .test-result {
                padding: 8px;
                margin: 5px 0;
                border-radius: 4px;
                display: flex;
                align-items: center;
                gap: 10px;
            }
            .test-result.success {
                background-color: #e8f5e9;
                border-left: 4px solid #4CAF50;
            }
            .test-result.failure {
                background-color: #ffebee;
                border-left: 4px solid #f44336;
            }
            .test-name {
                font-weight: bold;
                flex: 1;
            }
            .test-status {
                font-size: 18px;
            }
            .test-message {
                flex: 2;
                color: #666;
            }
            .test-time {
                color: #999;
                font-size: 12px;
            }
        `;
        document.head.appendChild(style);
    }
});


